package com.junit;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hcfly.utils.ESClient;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.mapper.RangeFieldMapper;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.BoostingQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.range.Range;
import org.elasticsearch.search.aggregations.metrics.cardinality.Cardinality;
import org.elasticsearch.search.aggregations.metrics.stats.extended.ExtendedStats;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;

import java.io.IOException;

public class CardinalityQueryDemo {
    private static final ObjectMapper mapper = new ObjectMapper();
    private static final String index = "fruit";
    private static final String type = "species";
    private static final RestHighLevelClient client = ESClient.getClient();

    @Test
    public void extendedStatesQuery() throws IOException {
        /**
         * 聚合查询，统计聚合查询。可以得到多个数值的统计指标，比如最大值，最小值。。。。
         */
        SearchRequest request = new SearchRequest(index);
        request.types(type);

        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 1,对范围进行计数
        builder.aggregation(AggregationBuilders.extendedStats("agg").field("size"));

        request.source(builder);

        SearchResponse resp = client.search(request, RequestOptions.DEFAULT);

        ExtendedStats agg = resp.getAggregations().get("agg");
        double sum = agg.getSum();//得到和
        double sumOfSquares = agg.getSumOfSquares();// 得到平方和
        System.out.println("和为：" + sum + ", 平方和为: " + sumOfSquares);


    }


    @Test
    public void rangeQuery() throws IOException {
        /**
         * 聚合查询，范围计数,包含数值，ip地址以及时间。
         */
        SearchRequest request = new SearchRequest(index);
        request.types(type);

        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 1,对范围进行计数
        builder.aggregation(AggregationBuilders.range("agg").field("size")
        .addUnboundedTo(4)
        .addRange(4,8)
        .addUnboundedFrom(8));

        request.source(builder);

        SearchResponse resp = client.search(request, RequestOptions.DEFAULT);

        Range agg = resp.getAggregations().get("agg");
        for (Range.Bucket bucket : agg.getBuckets()) {
            String key = bucket.getKeyAsString();
            Object from  = bucket.getFrom();
            Object to = bucket.getTo();
            long docCount = bucket.getDocCount();
            System.out.println("key:"+key+" from:" + from.toString() +
                    " to:" + to.toString() + " docCount:" + docCount);

        }


    }


    @Test
    public void cardinalityQuery() throws IOException {
        /**
         * 聚合查询，去重计数
         */
        SearchRequest request = new SearchRequest(index);
        request.types(type);

        SearchSourceBuilder builder = new SearchSourceBuilder();

        // 1,指定的聚合查询方式,对name字段进行去重查询
        builder.aggregation(AggregationBuilders.cardinality("agg").field("name"));

        request.source(builder);

        SearchResponse resp = client.search(request, RequestOptions.DEFAULT);

        Cardinality agg = resp.getAggregations().get("agg");
        System.out.println(agg.getValue());


    }


}
